package com.netx.generics.basic;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Timer;


public final class RootContext extends Context {

	// For Context:
	RootContext() {
		super("root", null);
		// Add property definitions for special properties:
		ContextRules rules = new ContextRules(true);
		rules.add(new PropertyDefinition("logger", Logger.class, false, false, new DefaultLogger()));
		rules.add(new PropertyDefinition("run-mode", RUN_MODE.class, false, false, RUN_MODE.PRD));
		rules.add(new PropertyDefinition("locale", String.class, false, false, Locale.getDefault().toString()));
		rules.add(new PropertyDefinition("tab-length", int.class, false, false, 4));
		rules.add(new PropertyDefinition("timer", Timer.class, true, false, new Timer(true)));
		try {
			super.applyRules(rules, false);
		}
		catch(RulesException re) {
			throw new IntegrityException(re);
		}
		// Add listener to apply special properties' actions:
		addPropertySetListener(new PropertySetListener() {
			public void onBeforeSet(Property p, Context c) {
				if(p.getName().equals("locale")) {
					Locale.setDefault(new Locale(p.stringValue()));
				}
			}
			public void onAfterSet(Property p, Context c) {
			}
		});
	}

	public Logger getLogger() {
		return (Logger)getProperty("logger").objectValue();
	}

	public RUN_MODE getRunMode() {
		return (RUN_MODE)getProperty("run-mode").objectValue();
	}

	public String getLocale() {
		return (String)getProperty("locale").objectValue();
	}

	public int getTabLength() {
		return getProperty("tab-length").intValue();
	}

	public Timer getTimer() {
		return (Timer)getProperty("timer").objectValue();
	}
	
	public void applyRules(ContextRules rules, boolean overwriteDefs) throws RulesException {
		Checker.checkNull(rules, "rules");
		List<String> errors = new ArrayList<String>();
		String[] specials = new String[] {"logger", "run-mode", "locale", "tab-length", "timer"};
		for(String s : specials) {
			if(rules.removeDefinitionFor(s) != null) {
				errors.add("cannot set rules for special property '"+s+"'");
			}
		}
		try {
			super.applyRules(rules, overwriteDefs);
		}
		catch(RulesException re) {
			errors.addAll(re.getContents().getErrors());
		}
		// Finalize:
		if(!errors.isEmpty()) {
			throw new RulesException(new ErrorList("errors applying ContextRules", errors));
		}
	}

	public void onDispose() {
		super.onDispose();
		getTimer().cancel();
	}

}
